Skip to main content

Agent 持久化执行

一句话:Agent 跑到第 18 步,进程挂了。这个专题讲怎么让它从第 18 步继续,而不是从头再来。

先约定几个词,本专题全程使用:

意思
持久化执行durable execution。让一段长时间运行的代码在进程崩溃、机器重启、版本发布之后仍能接着跑完。这个概念在分布式系统领域已经有二十年历史,Agent 只是把它变成了日常问题
检查点(checkpoint)把执行到某一步的状态存到进程外的存储里,崩溃后据此恢复
幂等同一个操作执行一次和执行多次,结果一样。这是整个专题里唯一没有任何框架能替你做的事
幂等键一个确定性的字符串(比如 任务ID:步骤号),随请求一起发给下游服务,让它据此去重
副作用代码对外部世界造成的、无法靠重跑抵消的改变:发出去的邮件、创建的工单、扣掉的钱
重放(replay)恢复时把代码从第一行重新跑一遍,已记录过的外部操作不真执行、直接返回历史返回值
确定性同样的输入必然走出同样的执行路径。重放式方案要求代码满足这一条,所以随机数、时间戳、模型调用都不能直接写在里面

一、这是 Agent 从 demo 到生产的分水岭

Demo 里的 Agent 跑 5 秒,挂了就重跑,没人在意。

生产上的 Agent 不一样:

  • 一个 Deep Research 任务跑 20 分钟、调 60 次模型、花掉几美元
  • 一个客服工单处理流程要等用户回复,可能挂起三天
  • 一个数据迁移 Agent 要跑 8 小时,中途 K8s 滚动更新把 Pod 干掉了

这三种情况下,"从头重跑"都不是一个可接受的答案 —— 不只是浪费钱,更要命的是副作用会重复:已经发出去的邮件会再发一遍,已经创建的工单会再建一个。

这个问题有一个成熟的名字:持久化执行(durable execution)。它在分布式系统领域已经有二十年历史,但 Agent 把它变成了一个几乎每个团队都会撞上的日常问题。

二、四条技术路线

四条路线的差异不在"用哪个产品",而在四个机制维度:状态存成什么形式、存在谁的存储里、崩溃后谁来重新拉起、以及对你的代码有没有确定性约束。

四条路线的差异不在「用哪个产品」,在这五个机制维度上维度① 框架内置LangGraph② 工作流引擎Temporal③ 数据库即状态DBOS④ 单二进制Restate什么时候写每个超级步结束以 Agent 图为单位每个 Command以 Workflow 函数为单位每个 step 一次写每条流再加两次每个被 run() 包住的不确定操作存什么快照 —— 当前的值channel_values事件历史 —— 调了什么返回了什么步骤输出 —— 输入加每一步的结果执行日志+ Awakeable 挂起点存在谁的存储你的 Postgres / SQLiteTemporal 集群,独立存储你的 Postgres 系统库Restate 运行时进程崩溃后谁拉起无人拉起要自己写巡检服务端调度自动接管另派一个 worker扫 PENDING 自动恢复多实例靠 Conductor运行时驱动自动恢复挂起时不占进程对你的代码有约束吗节点内可随意调模型模型调用须进 Activity每一步必须幂等漏包 run() 会静默出错「存什么」那一行决定了后面一切:只有 ① 存的是状态快照,另外三家存的都是「发生过什么」,恢复时要把代码重跑一遍。最后一行是最容易被宣传掩盖的代价 —— DBOS 主打「只要一个 Postgres」,降低的是运维成本,不是认知成本。
从左到右接入成本递增、能力递增。四条路线并不互斥:常见的生产组合是 LangGraph 管 Agent 图内部的状态,外面再套一层 Temporal 管整个业务流程的长事务。
← 接入成本低、能力受限       能力强、心智负担重 →

读这张图有三个要点:

第一行的"存成什么"决定了后面一切。 LangGraph 存的是状态快照(恢复时把值灌回去),另外三家存的都是发生过什么(恢复时把代码重跑一遍,已完成的操作直接返回记录值)。

第四行是 LangGraph 唯一的硬缺口。 它的检查点安静地躺在数据库里,除非有人拿着 thread_id 再调一次,任务就永远停在那儿。另外三家都有服务端或运行时负责发现并拉起。

第五行是最容易被宣传掩盖的代价。 DBOS 主打"只要一个 Postgres",但它和 Temporal 一样是重放式的,确定性约束一条不少。降低的是运维成本,不是认知成本 —— 只有 LangGraph 因为不重放代码,才真正没有这个负担。

四条路线不是互斥的。 常见的生产组合是:LangGraph 管 Agent 图内部的状态,外面套一层 Temporal 管整个业务流程的长事务。

三、五篇正文

#标题回答的问题主要拆解对象
01为什么需要从头重跑到底错在哪?从一个 30 步任务讲起,不需要前置知识
02LangGraph Checkpointer框架自带的方案能做到什么程度?libs/checkpoint/checkpoint-conformance/
03Temporal 与确定性重放为什么它要求你的代码"不许用随机数"?Event History 重放机制与确定性约束
04DBOS 与 Restate不想跑集群,还有别的选择吗?DBOS 的三阶段恢复 + Restate 的定位
05——我该选哪条路?全专题结论

四、拆解对象

项目协议语言为什么选它
langchain-ai/langgraph40,005MITPythonAgent 场景装机量最大,checkpointer 是一等公民
temporalio/temporal22,394MITGo持久化执行的工业标准,Uber 出身
restatedev/restate4,308Rust新一代,单二进制部署
dbos-inc/dbos-transact-py1,532MITPython路线最激进:直接把 Postgres 当状态机
resonatehq/resonate655Apache-2.0Rust最轻量,作为对照组

五、与其他专题的关系